package com.jyw.common.excel;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import net.sf.jsqlparser.expression.DateTimeLiteralExpression;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 对象反射转换
 *
 * @author FrogPrince
 */
public class ObjectParseUtils {

    private static Logger logger = LoggerFactory.getLogger(ObjectParseUtils.class);

    public static <T> void contactObjectSum(T sumObject, List<T> objectList) {
        if (CollectionUtils.isNotEmpty(objectList)) {
            List<Field> filedList = getFiledList(sumObject);
            filedList.forEach(field -> {
                // 设置属性是可以访问的
                field.setAccessible(true);
                Double sumValue = 0.00;
                for (Object object : objectList) {
                    Object value = getFieldValueByName(field.getName(), object);
                    if (null != value) {
                        if (Double.class.equals(getFiledType(field.getName(), sumObject))
                                || BigDecimal.class.equals(getFiledType(field.getName(), sumObject))) {
                            sumValue += Double.parseDouble(value.toString());
                        }
                    }
                }
                if (sumValue.equals(0.00)) {
                    sumValue = null;
                }
                try {
                    if (Double.class.equals(getFiledType(field.getName(), sumObject))
                            || BigDecimal.class.equals(getFiledType(field.getName(), sumObject))) {
                        field.set(sumObject, sumValue);
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            });
        }
    }

    public static <T> Map<String, String> objectToMap(T object) {
        Map<String, String> returnMap = new HashMap<>(200);
        List<String> fileNameList = getFiledName(object);
        fileNameList.forEach(result -> {
            Object value = getFieldValueByName(result, object);
            if (null != value) {
                if (Date.class.equals(getFiledType(result, object))) {
                    value = new SimpleDateFormat("yyyy-MM-dd").format((Date) value);
                }
                if (DateTimeLiteralExpression.DateTime.class.equals(getFiledType(result, object))) {
                    value = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((Date) value);
                }

                if (Double.class.equals(getFiledType(result, object))) {
                    if (Double.parseDouble(value.toString()) == 0.0) {
                        value = "";
                    }
                }
            } else {
                value = "";
            }
            returnMap.put(result, value.toString());
        });
        return returnMap;
    }

    public static <T> Map<String, String> objectToMapDateTime(T object) {
        Map<String, String> returnMap = new HashMap<>(200);
        List<String> fileNameList = getFiledName(object);
        fileNameList.forEach(result -> {
            Object value = getFieldValueByName(result, object);
            if (null != value) {
                if (Date.class.equals(getFiledType(result, object))) {
                    value = new SimpleDateFormat("yyyy-MM-dd").format((Date) value);
                }

                if (Double.class.equals(getFiledType(result, object))) {
                    if (Double.parseDouble(value.toString()) == 0.0) {
                        value = "";
                    }
                }
            } else {
                value = "";
            }
            returnMap.put(result, value.toString());
        });
        return returnMap;
    }

    /**
     * @param o
     * @return
     * @desc 获取属性数组
     */
    private static List<Field> getFiledList(Object o) {
        List<Field> fileList = new ArrayList<>();
        Class clazz = o.getClass();
        Class superClazz = clazz.getSuperclass();
        //处理本类的对象
        Field[] fields = clazz.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            fileList.add(fields[i]);
        }
        //处理父类的对象
        Field[] superFields = superClazz.getDeclaredFields();
        for (int i = 0; i < superFields.length; i++) {
            fileList.add(superFields[i]);
        }
        return fileList;
    }

    /**
     * @param o
     * @return
     * @desc 获取属性名数组
     */
    private static List<String> getFiledName(Object o) {
        List<String> fileNameList = new ArrayList<>();
        Class clazz = o.getClass();
        Class superClazz = clazz.getSuperclass();
        //处理本类的对象
        Field[] fields = clazz.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            fileNameList.add(fields[i].getName());
        }
        //处理父类的对象
        Field[] superFields = superClazz.getDeclaredFields();
        for (int i = 0; i < superFields.length; i++) {
            fileNameList.add(superFields[i].getName());
        }
        return fileNameList;
    }

    /**
     * @param fieldName
     * @param o
     * @return
     * @desc 根据属性名获取属性值
     */
    private static Object getFieldValueByName(String fieldName, Object o) {
        try {
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getter = "get" + firstLetter + fieldName.substring(1);
            Method method = o.getClass().getMethod(getter, new Class[]{});
            Object value = method.invoke(o, new Object[]{});
            return value;
        } catch (Exception e) {
            logger.error("获取属性值失败！" + e, e);
        }
        return null;
    }

    /**
     * @param fieldName
     * @param o
     * @return
     * @desc 获取属性的数据类型
     */
    private static Object getFiledType(String fieldName, Object o) {
        Class clazz = o.getClass();
        Class superClazz = clazz.getSuperclass();
        //处理类的对象
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (Objects.equals(fieldName, field.getName())) {
                return field.getType();
            }
        }
        //处理父类的对象
        Field[] superFields = superClazz.getDeclaredFields();
        for (Field field : superFields) {
            if (Objects.equals(fieldName, field.getName())) {
                return field.getType();
            }
        }
        return null;
    }

    /**
     * 判断对象中属性值是否全为空
     *
     * @param object
     * @return
     */
    public static boolean checkObjAllFieldsIsNull(Object object) {
        if (null == object) {
            return true;
        }
        try {
            for (Field f : object.getClass().getDeclaredFields()) {
                f.setAccessible(true);
                if (f.get(object) != null && StringUtils.isNotBlank(f.get(object).toString())) {
                    return false;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }


}
